import {apiPrefix} from './constant';
const storageKey = 'token';

declare interface RequestOption {
  ignoreLoginCheck?: boolean;
  initial?: false,
}

const callbackQueue: Array<Function> = [];
const wxLogin = function (success: Function) {
  //微信登录（会话）
  wx.login({
    success: function (res) {
      if (!res.code) {
        return;
      }
      let token = wx.getStorageSync(storageKey);
      wx.request({
        url: apiPrefix + 'login/wxLogin',
        data: {
          code: res.code
        },
        header: {
          "content-type": "application/x-www-form-urlencoded",
          "Authorization": token
        },
        method: 'POST',
        success: function (res: any) {
          setToken(res);
          if (res.data.code === '009') {
            //正在登录，插入回调队列
            if (success) {
              callbackQueue.push(success);
            }
            return;
          }
          if (res.data.code !== '000') {
            wx.showToast({
              title: res.data.message,
              icon: 'none'
            });
            return;
          }
          while (callbackQueue.length > 0) {
            //将队列内容取出并执行
            let callback = callbackQueue.shift();
            if (callback) {
              try {
                callback();
              } catch (e) {
                //
              }
            }
          }
          if (success) {
            success();
          }
        }
      });
    }
  });
}

const setToken = (res: any) => {
  let token = res.header['Token'];
  if (token) {
    wx.setStorageSync(storageKey, token);
  }
}

const doRequest = (url: string, method: 'GET' | 'POST', data?: any, option?: RequestOption, contentType?: string, responseType?: "text" | "arraybuffer" | undefined): Promise<any> => {
  wx.showLoading({
    title: '加载中',
  });
  let param = {
    url: url,
    data: data
  }
  let realDoRequest = function (param: any) {
    if (!param.data) {
      param.data = {};
    }
    let token = wx.getStorageSync(storageKey);
    if (!token) {
      token = '';
    }
    let url = param.url;
    let wholeUrl = apiPrefix + url;
    let data;
    let header: any = {
      'Authorization': token
    };
    if (method === 'GET') {
      //GET 拼接参数
      wholeUrl = urlAppendParam(wholeUrl, param.data);
      data = null;
    } else {
      //POST发送数据
      if (param.data instanceof Array) {
        data = Object.assign([], param.data);
      } else {
        data = Object.assign({}, param.data);
      }
      header['content-type'] = contentType;
    }

    wx.request({
      url: wholeUrl,
      data: data,
      header: header,
      method: method,
      responseType: responseType,
      success: function (res: any) {
        setToken(res);
        if (res.data.code === '001') {
          wxLogin(function () {
            realDoRequest(param);
          });
          return;
        }
        if (param.success) {
          param.success(res);
        }
      },
      fail: function (res) {
        if (param.fail) {
          param.fail(res);
        }
      },
      complete: function (res) {
        wx.hideLoading();
        if (param.complete) {
          param.complete(res);
        }
      }
    })
  }
  return new Promise((resolve) => {
    let app = getApp();
    if (app && app.reloadConfig) {
      app.reloadConfig();
    }
    realDoRequest({
      url: param.url,
      data: param.data,
      success(res: any) {
        if (option && option.ignoreLoginCheck) {
          resolve(res);
          return;
        }
        if (res.data.code === '002') {
          getApp().toPhoneLoginPage();
          return;
        }
        resolve(res);
      },
      fail: function () {
        //reject(res);
        resolve({
          data: {
            code: '999',
            message: '通信错误'
          }
        });
      }
    });
  });
}

const urlAppendParam = (url: string, param?: any): string => {
  if (!param) {
    return url;
  }
  if (!url.endsWith('?')) {
    return urlAppendParam(url + '?', param);
  }
  let array: Array<string> = [];
  for (const key in param) {
    if (Object.prototype.hasOwnProperty.call(param, key)) {
      const value = param[key];
      array.push(key + '=' + encodeURIComponent(value.toString()));
    }
  }
  return url + array.join('&');
}

export default {
  doRequest,
  wxLogin
}